package com.se.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

@Slf4j
public class ByteBufTest {

    //major ByteBuf非常重要, 双index, 自动扩容, 引用计数, 谁最后使用, 谁释放release [用前retain]
    // 对于netty环境, 入站msg, 如果不处理，由TailContext释放, buf->obj 使用或继承系统Encoder，则由Encoder释放，否则自己释放   出站msg, obj->buf后由ChannelOutboundBuffer释放，不需要处理
    public static void main(String[] args) {

        byte[] bytes = {1, 3, 5, 7, 9};

        /**
         *  ByteBuf 三种主要创建方式   通过Unpooled, allocate创建
         *  1.创建新的ByteBuf对象
         *  2.包装现有的字节数组byte[]， ByteBuffer对象或者字符串  wrap
         *  3.拷贝现有的字节数组byte[]， ByteBuffer对象 或者字符串。 copied
         */

        // int initialCapacity = 256, int maxCapacity = Integer.MAX_VALUE
        ByteBuf buf = Unpooled.buffer();

        buf = Unpooled.buffer(8, 256); //maxCapacity(256)
        int maxCapacity = buf.maxCapacity();  //256

        // heap Buffer 堆缓冲区 JVM 管理
        ByteBuf buf1 = Unpooled.buffer(1);
        buf1.capacity(10); //maxCapacity = Integer.MAX_VALUE
        maxCapacity = buf1.maxCapacity(); //MAX_VALUE

        // 直接缓冲区direct Buffer
        ByteBuf buf2 = Unpooled.directBuffer();

        // 包装方式 wrappedBuffer[共用bytes]
        ByteBuf buf3 = Unpooled.wrappedBuffer(bytes);
        // 拷贝方式 copiedBuffer
        ByteBuf buf4 = Unpooled.copiedBuffer(bytes);

        //set get不会修改index
        //buf1.setBytes(0, bytes);
        buf1.writeBytes(bytes);

        //直接读取unsignedShort, 不足两个字节自动补0x00
        //ByteBuf buf = Unpooled.buffer();
        //buf.writeBytes(new byte[]{1});
        //int unsignedShort = buf.getUnsignedShort(0);

        log.info("ByteBuf size： {}", buf1.capacity());


        // 随机访问索引、顺序访问索引
        for (int i = 0; i < buf1.capacity(); i++) {
            //log.info("byte {} = {}", i, buf1.getByte(i));
        }
        buf1.forEachByte(value -> true);

        buf1.writeByte(10); // write + 1

        ByteBuf byteBuf = buf1.readBytes(1);

        byte[] bytes1 = new byte[buf1.readableBytes()];
        buf1.readBytes(bytes1); // readable = write

//        buf1.readBytes(1); //readerIndex > writerIndex

        log.info(Arrays.toString(bytes1));
    }
}
